/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

import DAO.CustomerDAO;
import DAO.InvoiceDAO;
import DAO.ProductDAO;
import DAO.ProductcatDAO;
import GUI.Components.IToolbarPerformEvent;
import GUI.Components.JErrorProvider;
import GUI.Components.ToolbarEvent;
import POJO.*;
import Util.DataAccessUtil;
import Util.GuiUtil;
import Util.MsgUtil;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Nguyễn Thi Mỷ Diện (1140214)
 */
public class FrmInvoice extends JInternalFrame {

    /**
     * Creates new form FrmInvoice
     */
    private JErrorProvider jErrorControl;
    private org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(this.getClass().getName());
    
    public FrmInvoice() {
        initComponents();
        jErrorControl = new JErrorProvider();
        toolbarInvoice.setAllowEdit(false);
        tbInvoiceline.setModel(new InvoicelineTable(new ArrayList()));
        txtTotal.setValue((float)0); // tổng tiền ban đầu
        refreshControl(false);
        // Đăng ký sự kiện trên toolbar
        this.userControlForm();
    }
    
    private void loadInvoiceline(Invoice invoice) {
        List<Invoiceline> listInvoicelines;
        try {
            listInvoicelines = InvoiceDAO.getListInvoicelines(invoice.getId());
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex.fillInStackTrace());
            return;
        }
        tbInvoiceline.setModel(new InvoicelineTable(listInvoicelines));
    }
    
    private InvoicelineTable getModelInvoiceline(){
        return (InvoicelineTable) tbInvoiceline.getModel();
    }
    
    //<editor-fold defaultstate="collapsed" desc="Refresh, cập nhập lại trạng thái controls">
    private void refreshControl(boolean editing){ 
        cboInvoiceId.setEditable(editing);        
        btnAddInvoiceline.setEnabled(editing);
        btnRemoveInvoiceline.setEnabled(editing);
        cboCustomer.setEnabled(editing);
        cboProductType_Invoiceline.setEnabled(editing);
        cboProduct_Invoiceline.setEnabled(editing);
        txtUnitPrice_Invoiceline.setEnabled(editing);
        txtQuantity_Invoiceline.setEnabled(editing);
        dateInput_InvoiceDate.setEnabled(editing);
        
        if(editing){
            // reset combobox
            cboInvoiceId.setModel(new DefaultComboBoxModel());
            // set default date input
            dateInput_InvoiceDate.setDate(new Date());
            // set customer name
            
            // prepare edit table
            List<Productcat> listProductCat = null;
            try {
                listProductCat = ProductcatDAO.getListProductCats(1);
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex.fillInStackTrace());
            }
            GuiUtil.addListCombobox(cboProductType_Invoiceline, listProductCat, "getName");
            // clear table
            getModelInvoiceline().removeAllElement();
        }else{
            // show model again
            List<Invoice> listInvoices;
            try {
                listInvoices = InvoiceDAO.getListInvoices();
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex.fillInStackTrace());
                return;
            }
            
            GuiUtil.addListCombobox(cboInvoiceId, listInvoices, "getId");
            
            List<Customer> listCustomers;
            try {
                listCustomers = CustomerDAO.getListCustomer();
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex.fillInStackTrace());
                return;
            }
            GuiUtil.addListCombobox(cboCustomer, listCustomers, "getName");
            
            cboProductType_Invoiceline.setModel(new DefaultComboBoxModel());
            cboProduct_Invoiceline.setModel(new DefaultComboBoxModel());
        }
        
    }
    //</editor-fold>
    
    
    private void userControlForm() {
        toolbarInvoice.addEventPerformClick(new IToolbarPerformEvent() {

            @Override
            public void performEventAdd(ToolbarEvent evt) {
                refreshControl(true);
            }

            @Override
            public void performEventEdit(ToolbarEvent evt) {
                jErrorControl.clear();
                refreshControl(true);                 
            }

            @Override
            public void performEventDelete(ToolbarEvent evt) {
                if(cboInvoiceId.getSelectedItem() == null)
                    return;
                Invoice in;
                try {
                     in  = (Invoice) cboInvoiceId.getSelectedItem();
                } catch (Exception e) {
                    log.error(e.getMessage(),e.fillInStackTrace());
                    return;
                }
                if(MsgUtil.yesno("Bạn có muốn xóa hóa đơn: " +in.getId()+" hay không?")
                        == JOptionPane.YES_OPTION){
                    try {
                       // Set detail
                        in.setInvoicelines(new HashSet(getModelInvoiceline().getList()));
                        // Delete
                        DataAccessUtil.delete(in);
                        MsgUtil.info("Xóa thành công!");
                        // Refresh controls
                        refreshControl(false);
                    } catch (Exception e) {
                         log.error(e.getMessage(),e.fillInStackTrace());
                         MsgUtil.error("Có lỗi trong quá trình xóa!",
                                 e.getMessage());
                    }
                }                
            }

            @Override
            public void performEventSave(ToolbarEvent evt) {
                jErrorControl.clear();
                String id = (String)cboInvoiceId.getSelectedItem();
                if(cboInvoiceId.getSelectedItem().toString().isEmpty()){
                    jErrorControl.setError(cboInvoiceId, "Bạn chưa nhập mã phiếu");
                    evt.setIsError(true);
                    return;
                }
                try {
                    if(InvoiceDAO.checkExistsInvoice(id)){
                        MsgUtil.error("Hóa đơn \""+id+"\" đã tồn tại!");
                        evt.setIsError(true);
                        return;
                    }
                } catch (Exception ex) {
                    log.error(ex.getMessage(), ex.fillInStackTrace());
                    return;
                }
                
                Customer customer = (Customer) cboCustomer.getSelectedItem();
               
                Store store = new Store();
                store.setId(1);
                
                Invoice invoice = new Invoice();
                invoice.setId(id);
                invoice.setCustomer(customer);
                invoice.setStore(store);
                invoice.setInvoicedate(dateInput_InvoiceDate.getDate());
              
                for(Invoiceline iLine : getModelInvoiceline().getList()){
                    iLine.setInvoice(invoice);
                    invoice.getInvoicelines().add(iLine);
                   
                }
                // set tổng giá
                float totalPrice = (float) txtTotal.getValue();
                invoice.setTotalprice(totalPrice);
                // chưa thanh toán / lập phiếu thu
                invoice.setIspaid(false);
                try {
                    DataAccessUtil.insert(invoice);                    
                    MsgUtil.info("Lập phiếu thành công!");
                    refreshControl(false);
                } catch (Exception ex) {
                    log.error(ex.getMessage(),ex.fillInStackTrace());
                    MsgUtil.error("Có lỗi trong quá trình lập phiếu!",
                                 ex.getMessage() );
                }                
            }

            @Override
            public void performEventCancel(ToolbarEvent evt) {
                 refreshControl(false);
            }

            @Override
            public void performEventRefresh(ToolbarEvent evt) {
                refreshControl(false);
            }

            @Override
            public void performEventClose(ToolbarEvent evt) {
               if(MsgUtil.yesno("Bạn có muốn đóng chức năng lập hóa đơn?") == JOptionPane.YES_OPTION){
                    dispose();            
                }
                
            }
        });
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        toolbarInvoice = new GUI.Components.Toolbar();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        dateInput_InvoiceDate = new com.toedter.calendar.JDateChooser();
        cboCustomer = new javax.swing.JComboBox();
        cboInvoiceId = new javax.swing.JComboBox();
        txtEmployee = new javax.swing.JFormattedTextField();
        jPanelInvoiceLine = new javax.swing.JPanel();
        btnAddInvoiceline = new javax.swing.JButton();
        btnRemoveInvoiceline = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        cboProductType_Invoiceline = new javax.swing.JComboBox();
        jLabel7 = new javax.swing.JLabel();
        cboProduct_Invoiceline = new javax.swing.JComboBox();
        txtQuantity_Invoiceline = new javax.swing.JFormattedTextField();
        jLabel8 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tbInvoiceline = new javax.swing.JTable();
        jLabel9 = new javax.swing.JLabel();
        txtUnitPrice_Invoiceline = new javax.swing.JFormattedTextField();
        jLabel4 = new javax.swing.JLabel();
        txtTotal = new javax.swing.JFormattedTextField();

        setTitle("Hoá đơn");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Hóa đơn bán hàng", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 12))); // NOI18N

        jLabel2.setText("Nhân viên:");
        jLabel2.setName("jLabel_idNhanVien");

        jLabel1.setText("Hoá đơn:");
        jLabel1.setName("jLabel_idHoaDon");

        jLabel5.setText("Ngày xuất hoá đơn:");
        jLabel5.setName("jLabel_idNgayXuatHD");

        jLabel3.setText("Khách hàng:");
        jLabel3.setName("jLabel_idKhachHang");

        cboCustomer.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cboCustomer.setName("jCombobox_LoaiSP");

        cboInvoiceId.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cboInvoiceId.setName("jCombobox_LoaiSP");
        cboInvoiceId.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                cboInvoiceIdMouseEntered(evt);
            }
        });
        cboInvoiceId.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cboInvoiceIdItemStateChanged(evt);
            }
        });

        txtEmployee.setEditable(false);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cboCustomer, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(cboInvoiceId, 0, 180, Short.MAX_VALUE)
                    .addComponent(txtEmployee, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 72, Short.MAX_VALUE)
                .addComponent(jLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(dateInput_InvoiceDate, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(54, 54, 54))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(cboInvoiceId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(txtEmployee, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(cboCustomer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addContainerGap())
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(dateInput_InvoiceDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(0, 0, Short.MAX_VALUE))))
        );

        jPanelInvoiceLine.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Chi tiết hóa đơn", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 12))); // NOI18N

        btnAddInvoiceline.setText("Thêm");
        btnAddInvoiceline.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddInvoicelineActionPerformed(evt);
            }
        });

        btnRemoveInvoiceline.setText("Xóa");
        btnRemoveInvoiceline.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoveInvoicelineActionPerformed(evt);
            }
        });

        jLabel6.setText("Loại sản phẩm:");
        jLabel6.setName("jLabel_idNhanVien");

        cboProductType_Invoiceline.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cboProductType_InvoicelineItemStateChanged(evt);
            }
        });

        jLabel7.setText("Tên sản phẩm:");
        jLabel7.setName("jLabel_idNhanVien");

        cboProduct_Invoiceline.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cboProduct_InvoicelineItemStateChanged(evt);
            }
        });

        jLabel8.setText("Số lượng:");
        jLabel8.setName("jLabel_idNhanVien");

        tbInvoiceline.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Loại sản phẩm", "Sản phẩm", "Đơn giá", "Số lượng xuất", "Thành tiền"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Object.class, java.lang.Object.class, java.lang.Double.class, java.lang.Integer.class, java.lang.Double.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(tbInvoiceline);

        jLabel9.setText("Đơn giá:");
        jLabel9.setName("jLabel_idNhanVien");

        txtUnitPrice_Invoiceline.setEditable(false);

        jLabel4.setText("Tổng tiền:");
        jLabel4.setName("jLabel_idTongTien");

        javax.swing.GroupLayout jPanelInvoiceLineLayout = new javax.swing.GroupLayout(jPanelInvoiceLine);
        jPanelInvoiceLine.setLayout(jPanelInvoiceLineLayout);
        jPanelInvoiceLineLayout.setHorizontalGroup(
            jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1)
            .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                        .addComponent(btnAddInvoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRemoveInvoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                        .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelInvoiceLineLayout.createSequentialGroup()
                                        .addComponent(jLabel6)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(cboProductType_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                                        .addComponent(jLabel7)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(cboProduct_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGap(1, 1, 1)))
                                .addGap(80, 80, 80)
                                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel8)
                                    .addComponent(jLabel9))
                                .addGap(18, 18, 18)
                                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(txtQuantity_Invoiceline, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                                    .addComponent(txtUnitPrice_Invoiceline))
                                .addGap(0, 0, Short.MAX_VALUE))
                            .addGroup(jPanelInvoiceLineLayout.createSequentialGroup()
                                .addGap(0, 0, Short.MAX_VALUE)
                                .addComponent(jLabel4)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(txtTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap())))
        );
        jPanelInvoiceLineLayout.setVerticalGroup(
            jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelInvoiceLineLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(cboProductType_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtQuantity_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(cboProduct_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtUnitPrice_Invoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnAddInvoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnRemoveInvoiceline, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelInvoiceLineLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(5, 5, 5))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolbarInvoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
            .addComponent(jPanelInvoiceLine, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolbarInvoice, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanelInvoiceLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void btnAddInvoicelineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddInvoicelineActionPerformed
        jErrorControl.clear();
        int quantity;
        try {
            quantity = Integer.parseInt(txtQuantity_Invoiceline.getText());
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex.fillInStackTrace());
            jErrorControl.setError(txtQuantity_Invoiceline,
                    "Số lượng không hợp lệ!");
            return;
        }
        Product product = (Product) cboProduct_Invoiceline.getSelectedItem();
        // kiem tra xem sp nay con du so luong hay khong?
        if(product.getQuantity() < quantity){
            // Khong du de ban
            MsgUtil.error("Sản phẩm \""+product.getName()+"\" còn "
                        +product.getQuantity()+" "+product.getUnit().getName());
            return;
        }
  
        //List<Invoiceline> invoiceLines = getModelInvoiceline().getList();

        // Tạo chi tiết hóa đơn (với sản phẩm đã thêm)
        Invoiceline invoiceLine = new Invoiceline();
        invoiceLine.setProduct(product);
        // Tính giá cho thời điểm hiện tại, sau khi lập hóa đơn, giá sản phẩm có thay đổi
        // vẫn lấy giá cũ này
        invoiceLine.setUnitprice(product.getUnitprice());
        invoiceLine.setQuantity(quantity);
        //tính lại số lượng tồn
        invoiceLine.getProduct().setTotalinstock(product.getQuantity() - quantity);
        // Hiển thị lại tổng tiền hóa đơn
        float total = (float) txtTotal.getValue() + (quantity * product.getUnitprice());
        txtTotal.setValue(total); 
        // Thêm vào danh sách chi tiết hóa đơn
        getModelInvoiceline().addElement(invoiceLine);
        
    }//GEN-LAST:event_btnAddInvoicelineActionPerformed

    private void btnRemoveInvoicelineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveInvoicelineActionPerformed
        getModelInvoiceline().removeElement(tbInvoiceline.getSelectedRow());
    }//GEN-LAST:event_btnRemoveInvoicelineActionPerformed

    private void cboProductType_InvoicelineItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProductType_InvoicelineItemStateChanged
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            Productcat c = (Productcat) evt.getItem();
            try {
                List<Product> listProduct = ProductDAO.getListProducts(c.getId());
                GuiUtil.addListCombobox(cboProduct_Invoiceline, listProduct, "getName");
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex.fillInStackTrace());
            }
        }
    }//GEN-LAST:event_cboProductType_InvoicelineItemStateChanged

    private void cboInvoiceIdItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboInvoiceIdItemStateChanged
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            if (!(evt.getItem() instanceof Invoice)) {
                // Clear table
                getModelInvoiceline().removeAllElement();
                return;
            }
            Invoice i = (Invoice) evt.getItem();
            dateInput_InvoiceDate.setDate(i.getInvoicedate());
            txtEmployee.setText("NV lập hóa đơn");      
            txtTotal.setValue(i.getTotalprice());
            
             //cboCustomer.setSelectedItem(evt);
            loadInvoiceline(i);
            
        }
    }//GEN-LAST:event_cboInvoiceIdItemStateChanged

    private void cboInvoiceIdMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cboInvoiceIdMouseEntered
        // TODO add your handling code here:
    }//GEN-LAST:event_cboInvoiceIdMouseEntered

    private void cboProduct_InvoicelineItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProduct_InvoicelineItemStateChanged
          if(evt.getStateChange() == ItemEvent.SELECTED){
            Product p = (Product) evt.getItem();
            txtUnitPrice_Invoiceline.setValue(p.getUnitprice());
         }
    }//GEN-LAST:event_cboProduct_InvoicelineItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddInvoiceline;
    private javax.swing.JButton btnRemoveInvoiceline;
    private javax.swing.JComboBox cboCustomer;
    private javax.swing.JComboBox cboInvoiceId;
    private javax.swing.JComboBox cboProductType_Invoiceline;
    private javax.swing.JComboBox cboProduct_Invoiceline;
    private com.toedter.calendar.JDateChooser dateInput_InvoiceDate;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanelInvoiceLine;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tbInvoiceline;
    private GUI.Components.Toolbar toolbarInvoice;
    private javax.swing.JFormattedTextField txtEmployee;
    private javax.swing.JFormattedTextField txtQuantity_Invoiceline;
    private javax.swing.JFormattedTextField txtTotal;
    private javax.swing.JFormattedTextField txtUnitPrice_Invoiceline;
    // End of variables declaration//GEN-END:variables

}

//<editor-fold defaultstate="collapsed" desc="Detail warehouse table">
class InvoicelineTable  extends AbstractTableModel{
    
    private static final String[] columnNames = {"Loại sản phẩm", "Sản phẩm", "Đơn giá", "Số lượng", "Thành tiền"};
    
    private List<Invoiceline> list;
    
    public InvoicelineTable (List<Invoiceline> list) {
        this.list = list;
    }
    
    public List<Invoiceline> getList(){
        return this.list;
    }
    public void removeAllElement(){
        this.list.clear();
        fireTableDataChanged();
    }
    
    public void addElement(Invoiceline e) {
        // Adds the element in the last position in the list
        list.add(e);
        fireTableRowsInserted(list.size()-1, list.size()-1);
    }
    public void removeElement(int rowIndex){
        list.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }
    
    @Override
    public int getRowCount() {
        return list.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }
    @Override
    public String getColumnName(int index){
       return columnNames[index];
    }
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch(columnIndex) {
            case 0: return list.get(rowIndex).getProduct().getProductcat().getName();
            case 1: return list.get(rowIndex).getProduct().getName();
            case 2: return list.get(rowIndex).getProduct().getUnitprice(); 
            case 3: return list.get(rowIndex).getQuantity();
            case 4: 
                double total = list.get(rowIndex).getProduct().getUnitprice() 
                                * list.get(rowIndex).getQuantity();
                return total;  // hien thi len table
        }
        return null;
    }
//</editor-fold>

}